﻿//////////////////////////////////////////////////////////////////////////////
//
// Copyright © 1998-2024 Glodon Company Limited.
//
// Licensed under the MIT License
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the “Software”),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//////////////////////////////////////////////////////////////////////////////

#include "GmepEditComponentCmd.h"
#include "CommandIds.h"
#include "CommandRegister.h"
#include "ModuleNames.h"
#include "UIService.h"
#include "IGmepGcsProjectManager.h"
#include "IEditMode.h"
#include "IUiDocumentViewManager.h"
#include "IUiDocument.h"
#include "GmepComponentUpgradeUtils.h"
#include "GnufMessageBoardInterface.h"
#include "GapDocumentStatesManager.h"
#include "GmepDocumentStateSetting.h"
#include "IGmepGcsProjectManager.h"
#include "IGraphicsNodeReference.h"
#include "ISelection.h"
#include "ElementId.h"
#include "IInstance.h"
#include "IDocument.h"
#include "IFamily.h"
#include "IElementBasicInformation.h"
#include "IFamilyConfigElement.h"
#include "IType.h"
#include "ComponentSqlUtils.h"

#include "EnableCompileWarning_The_LAST_IncludeInCpp.h"

using namespace gcmp;
using namespace gmep;
using namespace gmepgcs;

REGISTER_COMMAND(GCS_MODULE_NAME, GmepEditComponentCmd)
GmepEditComponentCmd::GmepEditComponentCmd() : GmepCommandBase(ID_CMD_GMEP_EDIT_COMPONENT)
{
}

GmepEditComponentCmd::~GmepEditComponentCmd()
{

}

gcmp::OwnerPtr<gcmp::IAction> GmepEditComponentCmd::ExecuteCommand(const gcmp::CommandParameters& cmdParams)
{
    const GraphicsNodeReferenceOwnerPtrSet& selectedElems = ISelection::Get()->GetGraphicsNodeReferences();
    if (1 == selectedElems.size())
    {
        const gcmp::IDocument* pDoc = GetCurrentDocument();
        DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pDoc, L"pDoc is nullptr", L"GMEP", L"2024-01-30");
        auto it = selectedElems.cbegin();
        const ElementId selectedElemId = (*it)->GetElementId();
        const IElement* pSelectedElement = pDoc->GetElement(selectedElemId);
        DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pSelectedElement, L"pSelectedElement is nullptr", L"GMEP", L"2024-01-30");
        const gcmp::IInstance * pIntance = quick_cast<IInstance>(pSelectedElement);
        DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pIntance, L"pIntance is nullptr", L"GMEP", L"2024-01-30");
        const gcmp::IFamily* pFamily = pIntance->GetFamily();
        DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pFamily, L"pFamily is nullptr", L"GMEP", L"2024-01-30");
        const IElementBasicInformation* pBasicInformation = pFamily->GetBasicInformation();
        DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pBasicInformation, L"pBasicInformation is nullptr", L"GMEP", L"2024-01-30");
        std::wstring familyName = pBasicInformation->GetName();
        const IFamilyConfigElement* pFamilyConfigElement = gcmp::IFamilyConfigElement::GetFamilyConfigElementByName(pDoc, familyName);
        DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pFamilyConfigElement, L"pFamilyConfigElement is nullptr", L"GMEP", L"2024-01-30");
        const Int64 familyCloudId = pFamilyConfigElement->GetFamilyIdInCloud();
        const int32_t componentVersion = pFamilyConfigElement->GetFamilyVersionInCloud();
        std::wstring strFamilyId = gcmp::StringUtil::ToWString(familyCloudId);

        const IElementBasicInformation* pSelectedElementBasicInfo = pSelectedElement->GetBasicInformation();
        DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pSelectedElementBasicInfo, L"pSelectedElementBasicInfo is nullptr", L"GMEP", L"2024-01-30");
        const IType* pType = pSelectedElementBasicInfo->GetType();
        DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pType, L"pType is nullptr", L"GMEP", L"2024-01-30");
        const IElementBasicInformation* pTypeBasicInformation = pType->GetBasicInformation();
        DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pTypeBasicInformation, L"pTypeBasicInformation is nullptr", L"GMEP", L"2024-01-30");
        const std::wstring &familyTypeName = pTypeBasicInformation->GetName();

        IProjectManager* pPrjMgr = IProjectManager::Get();
        DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pPrjMgr, L"pPrjMgr is nullptr", L"GMEP", L"2024-01-30");
        const std::wstring projectId = IProjectManager::Get()->GetCurrentProjectId();
        const std::wstring enterpriseId = IProjectManager::Get()->GetCurrentEnterpriseId();

        std::wstring forbidOpenMessage = L"";
        if (!projectId.empty())
        {
            bool isAllowToOpen = false;
            std::wstring upgradeMessage;
            GmepComponentUpgradeUtils::GetIsAllowToOpenByProjectComponentLibUpgradeStatus(projectId, isAllowToOpen, upgradeMessage);
            if (!isAllowToOpen)
            {
                forbidOpenMessage = upgradeMessage;
            }
        }

        if (!forbidOpenMessage.empty())
        {
            gnuf::ShowMessageBoard(forbidOpenMessage, GBMP_TR(L"提示"), gnuf::eMB_OK | gnuf::eMB_ICONINFORMATION);
            return nullptr;
        }

        if (!ComponentSqlUtils::CheckComponentExisted(projectId, strFamilyId,familyTypeName))
        {
            gnuf::ShowMessageBoard(GBMP_TR(L"所选构件已在项目构件库中删除，不支持使用项目构件管理继续编辑！"), GBMP_TR(L"提示"), gnuf::eMB_OK | gnuf::eMB_ICONINFORMATION);
            return nullptr;
        }

        UIService* pUiservice = UIService::Get();
        DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pUiservice, L"pUiservice is nullptr", L"GMEP", L"2024-01-30");
        pUiservice->RefreshUIpermission();
        pUiservice->ShowMainWindow();
        pUiservice->SetIsByEditComponentShow(true);
        pUiservice->ShowProjectComponentEditingPage(projectId, enterpriseId, strFamilyId, componentVersion, familyName, familyTypeName);
    }
    return nullptr;
}

bool GmepEditComponentCmd::IsEnabledImpl() const
{
    IUiDocumentViewManager* pManager = IUiDocumentViewManager::Get();
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pManager, L"pManager is nullptr", L"GMEP", L"2024-01-30");
    gcmp::IUiDocument* pUIDoc = pManager->GetCurrentUiDocument();
    if (!pUIDoc)
    {
        return false;
    }
    gcmp::IDocument* pDoc = pUIDoc->GetDbDocument();
    if (!pDoc)
    {
        return false;
    }
    if (IEditMode::GetTopActiveEditMode(pDoc))
    {
        return false;
    }
    return  true;
}

bool GmepEditComponentCmd::IsVisibleImpl() const
{
    return IsCloudDocument();
}
